import { CanvasTextureBase, ICanvasTextureOptions } from './canvas-texture-base';
import { Scene } from '@babylonjs/core/scene';


/**
 * 色标对象
 * @param value 比例值
 * @param color 颜色
 */
interface IColorStop {
    value: number,
    color: string,
}

/**
 * 渐变画布纹理参数对象
 * @param drawRatio 绘制比例
 * @param x0 渐变的开始圆的 x 坐标
 * @param y0 渐变的开始圆的 y 坐标
 * @param x1 渐变的结束圆的 x 坐标
 * @param y1 渐变的结束圆的 y 坐标
 * @param r0 开始圆的半径
 * @param r1 结束圆的半径
 * @param radiant 是否圆形渐变（否则线性渐变）
 * @param offsetStart 开始色标偏移值（没有设置色标集合时使用）
 * @param colorStart 开始色标颜色值（没有设置色标集合时使用）
 * @param offsetEnd 结束色标偏移值（没有设置色标集合时使用）
 * @param colorEnd 结束色标颜色值（没有设置色标集合时使用）
 * @param colorStops 色标集合
 */
interface ICanvasTextureGradientOptions extends ICanvasTextureOptions {
    drawRatio?: number,
    x0?: number,
    y0?: number,
    x1?: number,
    y1?: number,
    r0?: number,
    r1?: number,
    radiant?: boolean,
    offsetStart?: number,
    colorStart?: string,
    offsetEnd?: number,
    colorEnd?: string,
    colorStops?: Array<IColorStop>
}


/**
 * 渐变画布纹理
 * @param name 名称
 * @param options 参数对象
 * @param scene 所在场景
 */
class CanvasTextureGradient extends CanvasTextureBase {

    constructor(name: string, options?: ICanvasTextureGradientOptions, scene?: Scene) {
        super(name, options, scene);
    }

    protected initialzeVariable(): void { }

    protected drawCanvas(options: ICanvasTextureGradientOptions): HTMLCanvasElement {
        const targetCanvas = options.canvas;
        const canvas = targetCanvas || document.createElement('canvas');
        const width = options.width || 64;
        const height = options.height || 64;
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext('2d')!;
        const ratio = options.drawRatio || 1;
        const dw = width * ratio;
        const dh = height * ratio;

        const x0 = options.x0 || 0;
        const y0 = options.y0 || dh;
        const x1 = options.x1 || 0;
        const y1 = options.y1 || 0;
        const r0 = options.r0 || dw;
        const r1 = options.r1 || dh;
        let grad: CanvasGradient;
        if (options.radiant) {
            grad = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
        } else {
            grad = ctx.createLinearGradient(x0, y0, x1, y1);
        }
        if (options.colorStops && options.colorStops.length > 1) {
            for (const cs of options.colorStops) {
                grad.addColorStop(cs.value, cs.color);
            }
        } else {
            grad.addColorStop(options.offsetStart || 0, options.colorStart || '#808080');
            grad.addColorStop(options.offsetEnd || 1, options.colorEnd || '#222222');
        }
        ctx.fillStyle = grad;
        ctx.fillRect((width - dw) * 0.5, (height - dh) * 0.5, dw, dh);

        return canvas;
    }

}


export { CanvasTextureGradient };
export type { ICanvasTextureGradientOptions };